﻿using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using Godot;
using KludgeBox;
using KludgeBox.Collections;
using KludgeBox.Events;
using KludgeBox.Events.Global;
using KludgeBox.Net;
using KludgeBox.Scheduling;
using VectorSurvivors.Multiplayer;

namespace VectorSurvivors.GameWorld;

public partial class World : Node2D
{
    [Export] [KludgeBox.NotNull] public Floor Floor { get; private set; }
    public bool IsReady { get; internal set; } = false;

    public Player Player { get; internal set; }
    public ReadOnlyHashSet<Enemy> Enemies => _enemies.AsReadOnly();
    public ReadOnlyHashSet<Character> Characters => _characters.AsReadOnly();
    

    private readonly HashSet<Player> _players = new();
    private readonly HashSet<Enemy> _enemies = new();
    private readonly HashSet<Character> _characters = new();

    /// <inheritdoc />
    public override void _Ready()
    {
        NotNullChecker.CheckProperties(this);
        EventBus.Publish(new RegisterWorldRequest(this));
        AddEntity(Game.Storages.Entities.Player.Instantiate<Player>());
    }

    public void AddEntity(Entity entity)
    {
        AddChild(entity);
        
        if (entity is Character character)
        {
            AddCharacter(character);
            return;
        }
    }
    
    public void AddCharacter(Character character)
    {
        _characters.Add(character);

        if (character is Player player)
        {
            _players.Add(player);
            
            Player = player;
            EventBus.Publish(new LocalPlayerSpawnedEvent(player));
        }

        if (character is Enemy enemy)
        {
            _enemies.Add(enemy);
        }
    }

    /// <inheritdoc />
    public override void _Process(double delta)
    {
        
    }

    /// <inheritdoc />
    public override void _PhysicsProcess(double delta)
    {
        
    }
}